package com.fishingwithme.android.ui.screens.map.handlers

import android.content.Context
import android.util.Log
import com.fishingwithme.android.ui.screens.map.DefaultMapWrapperController
import com.fishingwithme.android.ui.screens.map.MapOperationContext
import com.fishingwithme.android.ui.screens.map.MapWrapperController
import com.tencent.tencentmap.mapsdk.maps.TencentMap

abstract class BaseHandler : MapEventHandler {

    private var _mapController: MapWrapperController? = null

    override var initializeData: Boolean = false
    private var selectedMarker: com.tencent.tencentmap.mapsdk.maps.model.Marker? = null
    private var onPointSelected: ((Double, Double) -> Unit)? = null

    protected var _context: Context? = null
    protected val context: Context? get() = _context

    // Remove the old data property and use only the context for data access
    protected val data: MutableMap<String, Any>?
        get() = mapController?.mapContext?.data

    // Add access to the MapOperationContext
    protected val mapContext: MapOperationContext?
        get() = _mapController?.mapContext

    // Protected getter for mapController
    protected val mapController: MapWrapperController?
        get() = this._mapController

    private var _map: TencentMap? = null
    protected val map: TencentMap? get() = _map

    var isActive: Boolean = false

    // Provide access to map elements through the context
    protected val markers: List<com.tencent.tencentmap.mapsdk.maps.model.Marker>
        get() = mapContext?.getMarkers() ?: emptyList()

    protected val polygons: List<com.tencent.tencentmap.mapsdk.maps.model.Polygon>
        get() = mapContext?.getPolygons() ?: emptyList()

    protected val polylines: List<com.tencent.tencentmap.mapsdk.maps.model.Polyline>
        get() = mapContext?.getPolylines() ?: emptyList()

    fun initHandler(
        tencentMap: TencentMap,
        context: Context,
        controller: DefaultMapWrapperController
    ) {
        this._map = tencentMap
        this._context = context
        this.registerController(controller)
    }

    override fun active() {
        this.isActive = true
        this.action()
    }

    override fun action() {
        removeListeners()
        setupMapClickListener()
        this.doAction()
    }

    override fun deActive() {
        this.isActive = false
        removeListeners()
    }

    open fun removeListeners() {
        try {
            map?.setOnMapClickListener(null)
        } catch (e: Exception) {
            Log.w("BaseHandler", "Error removing map click listener", e)
        }

        onPointSelected = null

        try {
            selectedMarker?.remove()
        } catch (e: Exception) {
            Log.w("BaseHandler", "Error removing selected marker", e)
        }
        selectedMarker = null
    }

    open fun doAction() {
    }

    override fun registerController(controller: MapWrapperController) {
        this._mapController = controller
    }

    override fun reset() {
        // 重置处理器状态
        removeListeners()
    }

    /**
     * 设置点选择回调
     */
    fun setOnPointSelectedCallback(callback: (Double, Double) -> Unit) {
        this.onPointSelected = callback
    }

    private fun setupMapClickListener() {
        try {
            map?.setOnMapClickListener {
                // 移除之前的标记
                selectedMarker?.remove()

                // 在点击位置添加新标记
                val markerOptions = com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions(it)
                    .title("选定位置")
                    .infoWindowEnable(true)
                selectedMarker = map?.addMarker(markerOptions)

                // Add the marker to the context for management
                selectedMarker?.let { marker ->
                    mapContext?.addMarker(marker)
                }

                selectedMarker?.showInfoWindow()

                // 调用回调函数传递位置信息
                onPointSelected?.invoke(it.latitude, it.longitude)
            }
        } catch (e: Exception) {
            Log.w("BaseHandler", "Error setting up map click listener", e)
        }
    }

    /**
     * Helper method to add a marker to the map and context
     */
    protected fun addMarkerToMap(marker: com.tencent.tencentmap.mapsdk.maps.model.Marker) {
        try {
            mapContext?.addMarker(marker)
        } catch (e: Exception) {
            Log.w("BaseHandler", "Error adding marker to context", e)
        }
    }

    /**
     * Helper method to add a polygon to the map and context
     */
    protected fun addPolygonToMap(polygon: com.tencent.tencentmap.mapsdk.maps.model.Polygon) {
        try {
            mapContext?.addPolygon(polygon)
        } catch (e: Exception) {
            Log.w("BaseHandler", "Error adding polygon to context", e)
        }
    }

    /**
     * Helper method to add a polyline to the map and context
     */
    protected fun addPolylineToMap(polyline: com.tencent.tencentmap.mapsdk.maps.model.Polyline) {
        try {
            mapContext?.addPolyline(polyline)
        } catch (e: Exception) {
            Log.w("BaseHandler", "Error adding polyline to context", e)
        }
    }

    /**
     * Helper method to remove a marker from the map and context
     */
    protected fun removeMarkerFromMap(marker: com.tencent.tencentmap.mapsdk.maps.model.Marker) {
        try {
            mapContext?.removeMarker(marker)
        } catch (e: Exception) {
            Log.w("BaseHandler", "Error removing marker from context", e)
        }
    }

    /**
     * Helper method to remove a polygon from the map and context
     */
    protected fun removePolygonFromMap(polygon: com.tencent.tencentmap.mapsdk.maps.model.Polygon) {
        try {
            mapContext?.removePolygon(polygon)
        } catch (e: Exception) {
            Log.w("BaseHandler", "Error removing polygon from context", e)
        }
    }

    /**
     * Helper method to remove a polyline from the map and context
     */
    protected fun removePolylineFromMap(polyline: com.tencent.tencentmap.mapsdk.maps.model.Polyline) {
        try {
            mapContext?.removePolyline(polyline)
        } catch (e: Exception) {
            Log.w("BaseHandler", "Error removing polyline from context", e)
        }
    }
}